#ifdef __TINY_TEST__

#include "fw/vbb_Utils.h"

int main (void) 
{                  
    vbb_EssentialInit(FALSE);                       
    vbb_OUTPUT_Print(".\r\n");
    vbb_OUTPUT_Print(".\r\n");
    vbb_OUTPUT_Print(".\r\n");
    vbb_OUTPUT_Print("Hello, World!\r\n");
    vbb_OUTPUT_Print(".\r\n");
    vbb_OUTPUT_Print(".\r\n");
    vbb_OUTPUT_Print(".\r\n");    
    
    while (TRUE)
    {
        __WFI();
        vbb_WatchDog_CheckIn();
    }
}

#else
#include "fw/vbb_RTC.h"
#include "vbb_GSM.h"
#include "vbb_Header.h"
#include <string.h>
#include "lzjb.h"
#include "base64.h"
#include "vbb_FirmwareUtils.h"
#include "vbb_FLASHMEM.h"
#include "vbb_STORAGE.h"
#include "vbb_CARD.h"
#include "vbb_SENSOR.h"
#include "vbb_SAVE.h"
#include "vbb_GPS.h"
#include "vbb_METER.h"

VBB_RTC rtc;
bool debug_mode;
unsigned int startSec;
int attemptCount = 0;
extern VBB_FlashMem flashMem;
extern VBB_Storage storage;
unsigned bool cab_occupied; 

VBB_Pin status_pin;

void ReadAllPinStates(void)
{
    int i = 0;
    
    vbb_OUTPUT_Print("INFO: Get all pin states:\r\n");
    
    for (i = 0; i < 16; i++)
    {    
        if (i == 9) continue;
        
        vbb_PIN_Init(&status_pin, GPIOA, i, PIN_MODE_FLOATING_INPUT);
        vbb_CONSOLE_Printf("Pin PA%d has value of %d.\r\n", i, vbb_PIN_Get(&status_pin));
    }
    
    for (i = 0; i < 16; i++)
    {    
        vbb_PIN_Init(&status_pin, GPIOB, i, PIN_MODE_FLOATING_INPUT);
        vbb_CONSOLE_Printf("Pin PB%d has value of %d.\r\n", i, vbb_PIN_Get(&status_pin));
    }
    
    for (i = 0; i < 16; i++)
    {    
        vbb_PIN_Init(&status_pin, GPIOC, i, PIN_MODE_FLOATING_INPUT);
        vbb_CONSOLE_Printf("Pin PC%d has value of %d.\r\n", i, vbb_PIN_Get(&status_pin));
    }
    
    for (i = 0; i < 16; i++)
    {    
        vbb_PIN_Init(&status_pin, GPIOD, i, PIN_MODE_FLOATING_INPUT);
        vbb_CONSOLE_Printf("Pin PD%d has value of %d.\r\n", i, vbb_PIN_Get(&status_pin));
    }
    
    for (i = 0; i < 16; i++)
    {    
        vbb_PIN_Init(&status_pin, GPIOE, i, PIN_MODE_FLOATING_INPUT);
        vbb_CONSOLE_Printf("Pin PE%d has value of %d.\r\n", i, vbb_PIN_Get(&status_pin));
    }
    
    vbb_OUTPUT_Print("\r\n");
    vbb_OUTPUT_Print("\r\n");
}

void MAIN_Booted(void)
{
    vbb_FLASHMEM_PushMessageF("$BOOT,%d,%s,%s,%02d%02d%02d,%02d%02d%02d,%d,%s,%d",
                    VERSION,
                    storage.config.OwnerId,
                    storage.config.VehicleId,                    
                    rtc.hour,
                    rtc.minute,
                    rtc.second,
                    rtc.day,                
                    rtc.month,
                    rtc.year % 100,                    
                    vbb_RTC_GetSec() - startSec, // boot time
                    vbb_GSM_GetIMEI(),
                    vbb_BACKUP_GetInt(SAVE_GSM_BOOT_COUNT) // boot count
                    ); // imei    
    
    vbb_FLASHMEM_PushMessageF("$INFO,%d,%s,%s,%02d%02d%02d,%02d%02d%02d,\"%s\",\"%s\"",
                    VERSION,
                    storage.config.OwnerId,
                    storage.config.VehicleId,                    
                    rtc.hour,
                    rtc.minute,
                    rtc.second,
                    rtc.day,                
                    rtc.month,
                    rtc.year % 100,                    
                    "IMEI",
                    vbb_GSM_GetIMEI());
    
    vbb_FLASHMEM_PushMessageF("$INFO,%d,%s,%s,%02d%02d%02d,%02d%02d%02d,\"%s\",\"%s\"",
                    VERSION,
                    storage.config.OwnerId,
                    storage.config.VehicleId,                    
                    rtc.hour,
                    rtc.minute,
                    rtc.second,
                    rtc.day,                
                    rtc.month,
                    rtc.year % 100,                    
                    "So VIN",
                    storage.config.VIN);
    
    vbb_FLASHMEM_PushMessageF("$INFO,%d,%s,%s,%02d%02d%02d,%02d%02d%02d,\"%s\",\"%s\"",
                    VERSION,
                    storage.config.OwnerId,
                    storage.config.VehicleId,                    
                    rtc.hour,
                    rtc.minute,
                    rtc.second,
                    rtc.day,                
                    rtc.month,
                    rtc.year % 100,                    
                    "Ten Lai Xe",
                    storage.config.DriverName);
                    
    vbb_FLASHMEM_PushMessageF("$INFO,%d,%s,%s,%02d%02d%02d,%02d%02d%02d,\"%s\",\"%s\"",
                    VERSION,
                    storage.config.OwnerId,
                    storage.config.VehicleId,                    
                    rtc.hour,
                    rtc.minute,
                    rtc.second,
                    rtc.day,                
                    rtc.month,
                    rtc.year % 100,                    
                    "Bien So Xe",
                    storage.config.PlateNumber);
}

unsigned int last_tick;

bool booted;

int main (void) 
{          
    unsigned int startSec;
    debug_mode = FALSE;
    vbb_EssentialInit(debug_mode);                           
    startSec = vbb_RTC_GetSec();        
    
    vbb_OUTPUT_Print("\r\n");
    vbb_OUTPUT_Print("          ___    __    ______ _____      ______              \r\n");
    vbb_OUTPUT_Print("          __ |  / /_______  /____(_)________  /____          \r\n");
    vbb_OUTPUT_Print("          __ | / /_  _ \\_  __ \\_  /_  ___/_  /_  _ \\         \r\n");
    vbb_OUTPUT_Print("          __ |/ / /  __/  / / /  / / /__ _  / /  __/         \r\n");
    vbb_OUTPUT_Print("          _____/  \\___//_/ /_//_/  \\___/ /_/  \\___/          \r\n");
    vbb_OUTPUT_Print("                                                             \r\n");
    vbb_OUTPUT_Print("    ______________            ______ ______                  \r\n");
    vbb_OUTPUT_Print("    ___  __ )__  /_____ _________  /____  /___________  __   \r\n");
    vbb_OUTPUT_Print("    __  __  |_  /_  __ `/  ___/_  //_/_  __ \\  __ \\_  |/_/   \r\n");
    vbb_OUTPUT_Print("    _  /_/ /_  / / /_/ // /__ _  ,<  _  /_/ / /_/ /_>  <     \r\n");
    vbb_OUTPUT_Print("    /_____/ /_/  \\__,_/ \\___/ /_/|_| /_.___/\\____//_/|_|     \r\n");
    vbb_OUTPUT_Print("                                                             \r\n");        
    
    vbb_AdditionalInit();
    
    vbb_CONSOLE_Printf("                          v%1d.%02d                         \r\n", (VERSION / 100), (VERSION % 100));
#ifdef __FAILSAFE__    
    vbb_OUTPUT_Print("                       (Fail-safe)\r\n");   
#endif    
    vbb_OUTPUT_Print("\r\n");           
    
    vbb_LedSwitch(TRUE, TRUE);
    
    vbb_Buzz(100);
    
    /*ReadAllPinStates();*/
    
    vbb_RTC_Init(&rtc);    
           
    vbb_FLASHMEM_Init();        
    vbb_STORAGE_Init();
    vbb_SENSOR_Init();
    vbb_CARD_Init();
    vbb_METER_Init();                    
    
    vbb_CONSOLE_Printf("SAVE: Pulse collected: %u\r\n", vbb_BACKUP_GetInt(SAVE_COLLECTED_PULSE));
    vbb_CONSOLE_Printf("SAVE: Queue messages status: %u/%u/%u\r\n", vbb_BACKUP_GetInt(SAVE_FLASHMEM_HEAD), vbb_BACKUP_GetInt(SAVE_FLASHMEM_SEND), vbb_BACKUP_GetInt(SAVE_FLASHMEM_TAIL));
    vbb_CONSOLE_Printf("SAVE: Downloading firmware: %d, %u\r\n", vbb_BACKUP_Get(SAVE_GSM_FIRMWARE_DOWNLOADING), vbb_BACKUP_GetInt(SAVE_GSM_DOWNLOAD_VERSION));    
    if (vbb_BACKUP_GetInt(SAVE_GSM_DOWNLOAD_ADDR) != 0)
        vbb_CONSOLE_Printf("SAVE: Firmware download size: %u bytes.\r\n", vbb_BACKUP_GetInt(SAVE_GSM_DOWNLOAD_ADDR) - FLASH_HEX_ADDR);    
    
    if (vbb_DeviceModel() == CNS01)
    {
        if (!storage.config.OfflineMode)
            vbb_GSM_Init();
    }
    else if (vbb_DeviceModel() == CNS03 || vbb_DeviceModel() == BA01)
        vbb_GSM_Init();    
    
    vbb_GPS_Init();    
    vbb_LedSwitch(TRUE, FALSE);    
    vbb_CONSOLE_Printf("INFO: Boot successfully (%d secs).\r\n", vbb_RTC_GetSec() - startSec);
    
    booted = TRUE;
    
    vbb_BACKUP_SetInt(SAVE_GSM_BOOT_COUNT, vbb_BACKUP_GetInt(SAVE_GSM_BOOT_COUNT) + 1);
    
    vbb_RTC_Update(&rtc);        
    
    while (TRUE)
    {
        __WFI();                        
        vbb_RTC_Update(&rtc);        
        vbb_SENSOR_Update();
        vbb_METER_Flush();
        vbb_GPS_Flush();
        vbb_CONSOLE_Flush();
        if (!storage.config.OfflineMode)
            vbb_GSM_Update();
        vbb_WatchDog_CheckIn();
    }
}
#endif
